﻿package taurus.client.io;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;

import com.taurus.core.util.Logger;


/**
 * 网络监听/心跳
 * @author daixiwei	daixiwei15@126.com
 *
 */
public class LagMonitor extends TimerTask {
	private static final Logger	logger	= Logger.getLogger(LagMonitor.class);
	private int			_averagePingTime;
	private Timer		_pollTimer;
	private int			_queueSize;
	private int			_interval;
	private boolean		_run;
	private SocketEngine	_engine;
	private List<Long>	_valueQueue;
	private Queue<Long>	write_queue	= new LinkedList<Long>();

	public LagMonitor(SocketEngine engine, int interval, int queueSize) {
		if (interval < 1) {
			interval = 1;
		}
		_engine = engine;
		_valueQueue = new ArrayList<Long>();
		_queueSize = queueSize;
		_pollTimer = new Timer();
		_interval = interval * 1000;
		_averagePingTime = 1000;
	}

	public void fnPingPong() {
		long w_time = write_queue.poll();
		long item = System.currentTimeMillis() - w_time;
		if (_valueQueue.size() >= _queueSize) {
			_valueQueue.remove(0);
		}
		_valueQueue.add(item);
		if (_valueQueue.size() == 0) {
			_averagePingTime = 0;
		}
		int num = 0;
		for (int i = 0; i < _valueQueue.size(); ++i) {
			num += _valueQueue.get(i);
		}
		_averagePingTime = (num / _valueQueue.size());
	}

	/**
	 * 启动监听
	 */
	public void start() {
		if (!isRunning()) {
			this._run = true;
			_pollTimer.scheduleAtFixedRate(this, 0, _interval);
		}
	}

	/**
	 * 停止监听
	 */
	public void stop() {
		if (isRunning()) {
			this._run = false;
			_pollTimer.purge();
		}
	}

	public void destroy() {
		stop();
		_pollTimer.cancel();
		_pollTimer = null;
		_engine = null;
	}

	/**
	 * 平均Ping的时间
	 * @return
	 */
	public int getAveragePingTime() {
		return _averagePingTime;

	}

	public boolean isRunning() {
		return _run;

	}

	@Override
	public void run() {
		try {
			_engine._controller.sendPingPong();
			write_queue.offer(System.currentTimeMillis());
		} catch (IOException e) {
			logger.error(e);
		}
	}
}
